package com.ev.asl.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.ev.asl.config.JiateConstant;
import com.ev.asl.constant.AslConstant;
import com.ev.asl.dao.AssemblyDailyDao;
import com.ev.asl.dao.CheckResultDao;
import com.ev.asl.dao.CheckResultDetailDao;
import com.ev.asl.domain.*;
import com.ev.asl.dto.AssemblyDaily2Dto;
import com.ev.asl.dto.AssemblyDaily3Dto;
import com.ev.asl.dto.AssemblyDailyDetailDtO;
import com.ev.asl.dto.AssemblyDailyDto;
import com.ev.asl.service.*;
import com.ev.asl.vo.ApiResultVO2S;
import com.ev.asl.vo.CheckResultDetail2VO;
import com.ev.asl.vo.voBillOfPull.KisReceiveStockVo;
import com.ev.custom.domain.DictionaryDO;
import com.ev.custom.domain.FacilityDO;
import com.ev.custom.domain.MaterielDO;
import com.ev.custom.service.*;
import com.ev.framework.config.Constant;
import com.ev.framework.config.ConstantForGYL;
import com.ev.framework.config.ConstantForMES;
import com.ev.framework.exception.BDException;
import com.ev.framework.utils.*;
import com.ev.k3cloud.service.kingdeeMiddlewareService;
import com.ev.mes.dao.ProductionFeedingDetailDao;
import com.ev.mes.dao.ProductionPlanDao;
import com.ev.mes.domain.*;
import com.ev.mes.service.CheckProjectService;
import com.ev.mes.vo.WorkTimeVO;
import com.ev.scm.domain.StockInDO;
import com.ev.scm.domain.StockInItemDO;
import com.ev.scm.domain.StockOutDO;
import com.ev.scm.domain.StockOutItemDO;
import com.ev.scm.service.ConsumingStockOutService;
import com.ev.scm.service.StockOutService;
import com.ev.system.domain.UserDO;
import com.ev.system.service.UserService;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.lang3.tuple.Triple;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author 姚家乐
 * @since 2021/6/10 13:34
 */
@Slf4j
@Service
public class AssemblyDailyServiceImpl implements AssemblyDailyService {

    //基本路
    @Value("${org.ftp.basePath}")
    private String basePath;
    //本地路径
    @Value("${org.ftp.localPath}")
    private String localPath;

    @Autowired
    private AssemblyDailyDao dao;

    @Autowired
    private UserService userService;

    @Autowired
    private KisBasicsService kisBasicsService;

    @Autowired
    private FacilityService facilityService;

    @Autowired
    private MaterielService materielService;

    @Autowired
    private ProductionFeedingDetailDao productionFeedingDetailDao;
    @Autowired
    private CheckResultDao checkResultDao;
    @Autowired
    private CheckResultDetailDao checkResultDetailDao;
    @Autowired
    NoticeService noticeService;


    @Autowired
    private CheckResultService checkResultService;

    @Autowired
    private AssemblyInstructionService assemblyInstructionService;
    @Autowired
    private CheckProjectService checkProjectService;


    @Autowired
    private StockOutService stockOutService;


    @Autowired
    private kingdeeMiddlewareService kingdeeMiddlewareService;

    @Autowired
    private DictionaryService dictionaryService;

    @Autowired
    private KisBillOfPushService kisBillOfPushService;

    @Autowired
    private ConsumingStockOutService consumingStockOutService;


    @Override
    public int save(AssemblyDailyDO entity) {
        return dao.save(entity);
    }

    @Override
    public int save(AssemblyDailyDto dto) {
        Map<String, String> map = new HashMap<>();
        map.put("startTime1", dto.getStartTime1());
        map.put("startTime2", dto.getStartTime2());
        map.put("startTime3", dto.getStartTime3());
        map.put("startTime4", dto.getStartTime4());
        map.put("startTime5", dto.getStartTime5());
        map.put("startTime6", dto.getStartTime6());
        map.put("startTime7", dto.getStartTime7());
        map.put("startTime8", dto.getStartTime8());
        map.put("startTime9", dto.getStartTime9());
        map.put("startTime10", dto.getStartTime10());
        map.put("endTime1", dto.getEndTime1());
        map.put("endTime2", dto.getEndTime2());
        map.put("endTime3", dto.getEndTime3());
        map.put("endTime4", dto.getEndTime4());
        map.put("endTime5", dto.getEndTime5());
        map.put("endTime6", dto.getEndTime6());
        map.put("endTime7", dto.getEndTime7());
        map.put("endTime8", dto.getEndTime8());
        map.put("endTime9", dto.getEndTime9());
        map.put("endTime10", dto.getEndTime10());
        map.put("thing1", dto.getThing1());
        map.put("thing2", dto.getThing2());
        map.put("thing3", dto.getThing3());
        map.put("thing4", dto.getThing4());
        map.put("thing5", dto.getThing5());

        UserDO userDO = ShiroUtils.getUser();
        dto.setStaffingId(userDO.getUserId());
        dto.setStaffingName(userDO.getName());
        dto.setWorkTimeMap(JSON.toJSONString(map));
        dto.setWorkTimeMap2(ObjectUtils.isEmpty(dto.getTableData()) ? null : JSON.toJSONString(dto.getTableData()));
//        dto.setWorkTimeMap2(dto.getTableDate2());
        dto.setStatus(AslConstant.AssemblyDaily.PLAN.getType());

        AssemblyDailyDO entity = new AssemblyDailyDO();
        SpringUtils.copyPropertiesIgnoreNull(dto, entity);
        int result = dao.save(entity);
        if (result > AslConstant.ZERO) {
            dto.setId(entity.getId());
            return result;
        }
        //给用户提示
        List<Long> toUsers = new ArrayList<>();
        toUsers.add(272l);
        noticeService.sendCheckMessage(entity.getId(), toUsers, "组装日报新增提醒", "/jobShop/accessoriesDaily_add?id=", "组装日报新增提醒");
        return AslConstant.ZERO;
    }

    @Override
    public R save2(AssemblyDaily2Dto dto) {
        Map<String, Object> result = Maps.newHashMapWithExpectedSize(1);
        Map<String, String> map = new HashMap<>();
        map.put("startTime1", dto.getStartTime1());
        map.put("startTime2", dto.getStartTime2());
        map.put("startTime3", dto.getStartTime3());
        map.put("startTime4", dto.getStartTime4());
        map.put("startTime5", dto.getStartTime5());
        map.put("startTime6", dto.getStartTime6());
        map.put("startTime7", dto.getStartTime7());
        map.put("startTime8", dto.getStartTime8());
        map.put("startTime9", dto.getStartTime9());
        map.put("startTime10", dto.getStartTime10());
        map.put("startTime11", dto.getStartTime11());
        map.put("startTime12", dto.getStartTime12());
        map.put("endTime1", dto.getEndTime1());
        map.put("endTime2", dto.getEndTime2());
        map.put("endTime3", dto.getEndTime3());
        map.put("endTime4", dto.getEndTime4());
        map.put("endTime5", dto.getEndTime5());
        map.put("endTime6", dto.getEndTime6());
        map.put("endTime7", dto.getEndTime7());
        map.put("endTime8", dto.getEndTime8());
        map.put("endTime9", dto.getEndTime9());
        map.put("endTime10", dto.getEndTime10());
        map.put("endTime11", dto.getEndTime11());
        map.put("endTime12", dto.getEndTime12());
        map.put("thing1", dto.getThing1());
        map.put("thing2", dto.getThing2());
        map.put("thing3", dto.getThing3());
        map.put("thing4", dto.getThing4());
        map.put("thing5", dto.getThing5());
        map.put("thing6",dto.getThing6());


        //前端组件弄不了时区，要后端转)
        if (!ObjectUtils.isEmpty(dto.getTableData())) {
            for (WorkTimeVO timeVO : dto.getTableData()) {
                if (!ObjectUtils.isEmpty(timeVO.getValue2()) && !ObjectUtils.isEmpty(timeVO.getValue2().get(0))) {
                    List<Date> value2 = new ArrayList<>();
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(timeVO.getValue2().get(0));
                    calendar.set(Calendar.HOUR, calendar.get(Calendar.HOUR) + 8);
                    value2.add(calendar.getTime());

                    Calendar calendar2 = Calendar.getInstance();
                    calendar2.setTime(timeVO.getValue2().get(1));
                    calendar2.set(Calendar.HOUR, calendar2.get(Calendar.HOUR) + 8);
                    value2.add(calendar2.getTime());

                    timeVO.setValue2(value2);
                }
                if (!ObjectUtils.isEmpty(timeVO.getValue1()) && !ObjectUtils.isEmpty(timeVO.getValue1().get(0))) {
                    List<Date> value1 = new ArrayList<>();
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(timeVO.getValue1().get(0));
                    calendar.set(Calendar.HOUR, calendar.get(Calendar.HOUR) + 8);
                    value1.add(calendar.getTime());
                    Calendar calendar2 = Calendar.getInstance();
                    calendar2.setTime(timeVO.getValue1().get(1));
                    calendar2.set(Calendar.HOUR, calendar2.get(Calendar.HOUR) + 8);
                    value1.add(calendar2.getTime());
                    timeVO.setValue1(value1);
                }
            }
        }

        UserDO userDO = ShiroUtils.getUser();
        dto.setStaffingId(userDO.getUserId());
        dto.setStaffingName(userDO.getName());
        dto.setWorkTimeMap2(ObjectUtils.isEmpty(dto.getTableData()) ? null : JSON.toJSONString(dto.getTableData()));
//        dto.setWorkTimeMap2(dto.getTableDate2());
        dto.setWorkTimeMap(JSON.toJSONString(map));
        if (ObjectUtils.isEmpty(dto.getStatus())) {
            dto.setStatus(AslConstant.AssemblyDaily.PLAN.getType());
        }

        dto.setDelFlag(0);

        AssemblyDailyDO entity = new AssemblyDailyDO();
        SpringUtils.copyPropertiesIgnoreNull(dto, entity);
        int count = dao.save(entity);
        dto.setId(entity.getId());
        result.put("id", entity.getId());
        if (count <= AslConstant.ZERO) {
            return R.error("未填写日报详情！");
        }
        List<AssemblyDailyDetailDtO> dailyDetails = dto.getDailyDetails();
        List<Long> aiIds = dailyDetails.stream().map(AssemblyDailyDetailDtO::getAiId).collect(Collectors.toList());
        HashMap<String, Object> instructionMap = new HashMap<>();
        instructionMap.put("ids", aiIds);
        List<AssemblyInstructionDO> instructionDOs = assemblyInstructionService.list(instructionMap);
        Map<Long, AssemblyInstructionDO> instructionGroup = instructionDOs.stream().collect(Collectors.toMap(AssemblyInstructionDO::getId, v -> v));

        List<Long> materielIds = dailyDetails.stream().map(AssemblyDailyDetailDtO::getMaterielId).collect(Collectors.toList());


        //保存日报详情并反写指示单的剩余数量
        dailyDetails.forEach(detail -> {
            detail.setAdId(entity.getId());
            AssemblyInstructionDO instructionDO = instructionGroup.get(detail.getAiId());
            instructionDO.setResidue(instructionDO.getResidue().subtract(ObjectUtils.isEmpty(detail.getProductionQty()) ? BigDecimal.ZERO : detail.getProductionQty()));
        });
        dao.batchSaveDetails(dailyDetails);
        assemblyInstructionService.batchUpdate(instructionDOs);

        //生成检验书
//        Map<String, Object> checkProjectMap = Maps.newHashMapWithExpectedSize(5);
//        checkProjectMap.put("materielIds", materielIds);
//        List<CheckResultDetail2VO> checkProjects = checkProjectService.list3(checkProjectMap);
//        if (ObjectUtils.isEmpty(checkProjects)){
//            return R.ok(result);
//        }
//        Map<Long, List<CheckResultDetail2VO>> checkProjectGroup = checkProjects.stream().collect(Collectors.groupingBy(CheckResultDetail2VO::getMaterielId));
//        ArrayList<CheckResultDO> checkResultDOS = new ArrayList<>();
//        List<CheckResultDetailDO> resultDetailDOS = new ArrayList<>();
//        dailyDetails.forEach(detail -> {
//            AssemblyInstructionDO instructionDO = instructionGroup.get(detail.getAiId());
//            List<CheckResultDetail2VO> checkProjectByMateriel = checkProjectGroup.get(detail.getMaterielId());
//            CheckResultDO resultDO = new CheckResultDO();
//            resultDO.setInstructionId(instructionDO.getId());
//            resultDO.setProduct(instructionDO.getMaterielName());
//            resultDO.setInstructionNo(instructionDO.getSerialNo());
//            resultDO.setProductionDate(instructionDO.getIndicateDate());
//            resultDO.setProductId(instructionDO.getMaterielId());
//            resultDO.setDailyId(instructionDO.getId());
//            resultDO.setDailyNo(instructionDO.getSerialNo());
////            resultDO.setQualityInspectorId(ShiroUtils.getUserId());
////            resultDO.setQualityInspectorName(ShiroUtils.getUser().getName());
//            resultDO.setInstructionQty(detail.getQualifiedQty());
////            resultDO.setQualityInspectorId(ShiroUtils.getUserId());
////            resultDO.setQualityInspectorName(ShiroUtils.getUser().getName());
//            resultDO.setStatus(AslConstant.NO);
//            resultDO.setDelFlag(AslConstant.NO);
//            resultDO.setBillDate(new Date());
//            resultDO.setType(AslConstant.YES);
//
//            String prefix = DateFormatUtil.getWorkOrderno(ConstantForMES.CHECK_PLAN_JCCJ, new Date());
//            Map<String, Object> params = Maps.newHashMapWithExpectedSize(3);
//            params.put("checkNo", prefix);
//            params.put("offset", 0);
//            params.put("limit", 1);
//            List<CheckResultDO> checkResultDOList = checkResultDao.list(params);
//            String suffix = null;
//            if (checkResultDOList.size() > 0) {
//                suffix = checkResultDOList.get(0).getCheckNo();
//            }
//            resultDO.setCheckNo(DateFormatUtil.getWorkOrderno(prefix, suffix));
//            resultDO.setIsChooseShow(2);
//            resultDO.setMaterielId(detail.getMaterielId());
//            List<CheckResultDetailDO> detailDOS = checkResult(checkProjectByMateriel, resultDO);
//            checkResultDOS.add(resultDO);
////            resultDetailDOS.addAll(detailDOS);
//        });
//        if(ObjectUtils.isEmpty(checkResultDOS)){
//            return R.ok(result);
//        }
//        checkResultDao.batchSave(checkResultDOS);
//        checkResultDOS.forEach(check ->{
//            List<CheckResultDetail2VO> checkProjectByMateriel = checkProjectGroup.get(check.getMaterielId());
//            checkResultService.sendCheckMessage(check.getId());
//            List<CheckResultDetailDO> detailDOS = checkResult(checkProjectByMateriel, check);
//            resultDetailDOS.addAll(detailDOS);
//        });
//        checkResultDetailDao.batchSave(resultDetailDOS);

        //给用户提示
//        List<Long> toUsers = new ArrayList<>();
//        toUsers.add(272l);
//        noticeService.sendCheckMessage(entity.getId(),toUsers,"组装日报新增提醒", "/jobShop/accessoriesDaily_add?id=","组装日报新增提醒");
        return R.ok(result);
    }


    @Override
    public R update2(AssemblyDaily3Dto dto) {
        Map<String, String> map = new HashMap<>();
        map.put("startTime1", dto.getStartTime1());
        map.put("startTime2", dto.getStartTime2());
        map.put("startTime3", dto.getStartTime3());
        map.put("startTime4", dto.getStartTime4());
        map.put("startTime5", dto.getStartTime5());
        map.put("startTime6", dto.getStartTime6());
        map.put("startTime7", dto.getStartTime7());
        map.put("startTime8", dto.getStartTime8());
        map.put("startTime9", dto.getStartTime9());
        map.put("startTime10", dto.getStartTime10());
        map.put("startTime11", dto.getStartTime11());
        map.put("startTime12", dto.getStartTime12());
        map.put("endTime1", dto.getEndTime1());
        map.put("endTime2", dto.getEndTime2());
        map.put("endTime3", dto.getEndTime3());
        map.put("endTime4", dto.getEndTime4());
        map.put("endTime5", dto.getEndTime5());
        map.put("endTime6", dto.getEndTime6());
        map.put("endTime7", dto.getEndTime7());
        map.put("endTime8", dto.getEndTime8());
        map.put("endTime9", dto.getEndTime9());
        map.put("endTime10", dto.getEndTime10());
        map.put("endTime11", dto.getEndTime11());
        map.put("endTime12", dto.getEndTime12());
        map.put("thing1", dto.getThing1());
        map.put("thing2", dto.getThing2());
        map.put("thing3", dto.getThing3());
        map.put("thing4", dto.getThing4());
        map.put("thing5", dto.getThing5());
        map.put("thing5", dto.getThing6());


        //前端组件弄不了时区，要后端转换
        if (!ObjectUtils.isEmpty(dto.getTableData())) {
            for (WorkTimeVO timeVO : dto.getTableData()) {
                if (!ObjectUtils.isEmpty(timeVO.getValue2()) && !ObjectUtils.isEmpty(timeVO.getValue2().get(0))) {
                    List<Date> value2 = new ArrayList<>();
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(timeVO.getValue2().get(0));
                    calendar.set(Calendar.HOUR, calendar.get(Calendar.HOUR) + 8);
                    value2.add(calendar.getTime());
                    Calendar calendar2 = Calendar.getInstance();
                    calendar2.setTime(timeVO.getValue2().get(1));
                    calendar2.set(Calendar.HOUR, calendar2.get(Calendar.HOUR) + 8);
                    value2.add(calendar2.getTime());
                    timeVO.setValue2(value2);
                }
                if (!ObjectUtils.isEmpty(timeVO.getValue1()) && !ObjectUtils.isEmpty(timeVO.getValue1().get(0))) {
                    List<Date> value1 = new ArrayList<>();
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(timeVO.getValue1().get(0));
                    calendar.set(Calendar.HOUR, calendar.get(Calendar.HOUR) + 8);
                    value1.add(calendar.getTime());
                    Calendar calendar2 = Calendar.getInstance();
                    calendar2.setTime(timeVO.getValue1().get(1));
                    calendar2.set(Calendar.HOUR, calendar2.get(Calendar.HOUR) + 8);
                    value1.add(calendar2.getTime());
                    timeVO.setValue1(value1);
                }
            }
        }

        List<AssemblyDailyDetailDtO> dailyDetails = dto.getDailyDetails();
        List<Long> aiIds = dailyDetails.stream().map(AssemblyDailyDetailDtO::getAiId).collect(Collectors.toList());
        HashMap<String, Object> instructionMap = new HashMap<>();
        instructionMap.put("ids", aiIds);
        List<AssemblyInstructionDO> instructionDOs = assemblyInstructionService.list(instructionMap);
        Map<Long, AssemblyInstructionDO> instructionGroup = instructionDOs.stream().collect(Collectors.toMap(AssemblyInstructionDO::getId, v -> v));
        AssemblyDaily2Dto assemblyDaily2DO = dao.getDetailInfo2(dto.getId());
        List<AssemblyDailyDetailDtO> dailyDetailDOS = assemblyDaily2DO.getDailyDetails();
        Map<Long, AssemblyDailyDetailDtO> dailyDetailDOSMapId = dailyDetailDOS.stream().collect(Collectors.toMap(AssemblyDailyDetailDtO::getId, v -> v, (v1, v2) -> v1));

        //保存日报详情并反写指示单的剩余数量
        dailyDetails.forEach(detail -> {
            AssemblyInstructionDO instructionDO = instructionGroup.get(detail.getAiId());
            AssemblyDailyDetailDtO detailDtO = dailyDetailDOSMapId.get(detail.getId());
            BigDecimal subtract = detail.getProductionQty().subtract(detailDtO.getProductionQty());
            instructionDO.setResidue(instructionDO.getResidue().subtract(subtract));
        });
        assemblyInstructionService.batchUpdate(instructionDOs);
//        dto.setWorkTimeMap2(dto.getTableDate2());
        dto.setWorkTimeMap2(ObjectUtils.isEmpty(dto.getTableData()) ? null : JSON.toJSONString(dto.getTableData()));
        dto.setWorkTimeMap(JSON.toJSONString(map));
        AssemblyDailyDO entity = new AssemblyDailyDO();
        SpringUtils.copyPropertiesIgnoreNull(dto, entity);
        int result = dao.update(entity);
        dao.batchUpdateDetails(dto.getDailyDetails());
        ////给用户提示
        //if(!AslConstant.AssemblyDaily.SUBMITTED.getType().equals(dto.getStatus())){
        //    List<Long> toUsers = new ArrayList<>();
        //    toUsers.add(272l);
        //    noticeService.sendCheckMessage(entity.getId(),toUsers,"组装日报修改提醒", "/jobShop/accessoriesDaily_add?id=","组装日报修改提醒");
        //}
        return R.ok("修改成功");
    }

    /**
     * 生产检察书
     *
     * @param checkResultDetail2VOS
     */
    private List<CheckResultDetailDO> checkResult(List<CheckResultDetail2VO> checkResultDetail2VOS, CheckResultDO resultDO) {
        List<CheckResultDetailDO> detailDOS = new ArrayList<>();
        checkResultDetail2VOS.forEach(check -> {
            CheckResultDetailDO detailDO = new CheckResultDetailDO();
            detailDO.setCheckItemId(check.getCheckItemId());
            detailDO.setCheckTypeId(check.getCheckTypeId());
            detailDO.setSize(check.getSize());
            if (!Constant.QIMI.equals(check.getCheckItem())) {
                detailDO.setSample(check.getSample());
            } else {
                detailDO.setSample(ObjectUtils.isEmpty(resultDO.getInstructionQty()) ? "" : "(※1)=" + resultDO.getInstructionQty());
            }
            detailDO.setCheckItem(check.getCheckItem());
            detailDO.setCheckWay(check.getCheckWay());
            detailDO.setFormula(check.getFormula());
            detailDO.setSpecification(check.getSpecification());
            detailDO.setMainId(resultDO.getId());
            detailDOS.add(detailDO);
        });
        return detailDOS;

    }

    @Override
    public AssemblyDailyDO get(Long id) {
        return dao.get(id);
    }

    @Override
    public Map<String, Object> getDetailInfo(Long id) {
        Map<String, Object> result = dao.getDetailInfo(id);
        result.put("indicateDate", DateUtils.format((Date) result.get("indicateDate")));

        //工作时间
        String workTimeMapJson = String.valueOf(result.get("workTimeMap2"));
        List<WorkTimeVO> workTimeVOS = JSON.parseArray(workTimeMapJson, WorkTimeVO.class);
//        result.putAll(JSON.parseObject(workTimeMapJson, Map.class));

        //前端展示的是世界时区，所以要转成世界时区
        if (!ObjectUtils.isEmpty(workTimeVOS)) {
            for (WorkTimeVO timeVO : workTimeVOS) {
                if (!ObjectUtils.isEmpty(timeVO.getValue2()) && !ObjectUtils.isEmpty(timeVO.getValue2().get(0))) {
                    List<Date> value2 = new ArrayList<>();
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(timeVO.getValue2().get(0));
                    calendar.set(Calendar.HOUR, calendar.get(Calendar.HOUR) + 8);
                    value2.add(calendar.getTime());
                    Calendar calendar2 = Calendar.getInstance();
                    calendar2.setTime(timeVO.getValue2().get(1));
                    calendar2.set(Calendar.HOUR, calendar2.get(Calendar.HOUR) + 8);
                    value2.add(calendar2.getTime());
                    timeVO.setValue2(value2);
                }
                if (!ObjectUtils.isEmpty(timeVO.getValue1()) && !ObjectUtils.isEmpty(timeVO.getValue1().get(0))) {
                    List<Date> value1 = new ArrayList<>();
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(timeVO.getValue1().get(0));
                    calendar.set(Calendar.HOUR, calendar.get(Calendar.HOUR) + 8);
                    value1.add(calendar.getTime());
                    Calendar calendar2 = Calendar.getInstance();
                    calendar2.setTime(timeVO.getValue1().get(1));
                    calendar2.set(Calendar.HOUR, calendar2.get(Calendar.HOUR) + 8);
                    value1.add(calendar2.getTime());
                    timeVO.setValue1(value1);
                }
            }
        }
        result.put("tableDate2", workTimeVOS);

        //原料投入量
        String feedingMaterialJson = JSONObject.toJSONString(result.get("feedingMaterial"));
        Object b = JSON.parse(feedingMaterialJson);
        Object c = JSON.parse(b.toString());
        JSONArray feedingMaterial = JSON.parseArray(c.toString());
        result.put("feedingMaterial", feedingMaterial);

        return result;
    }

    @Override
    public Map<String, Object> getDetailInfo2(Long id) {
        AssemblyDaily2Dto assemblyDaily2Dto = dao.getDetailInfo2(id);
        assemblyDaily2Dto.setIndicateDate2(DateUtils.format(assemblyDaily2Dto.getIndicateDate()));
        Map<String, Object> result = JSON.parseObject(JSON.toJSONString(assemblyDaily2Dto), new TypeReference<Map<String, Object>>() {
        });
        result.put("indicateDate", DateUtils.format((Date) result.get("indicateDate")));
        if (result.containsKey("startDate") && !ObjectUtils.isEmpty(result.get("startDate"))) {
//            result.put("indicateDate",assemblyDaily2Dto.getIndicateDate2());
            result.put("startDate", DateUtils.format(assemblyDaily2Dto.getStartDate(), DateUtils.DATE_TIME_PATTERN));
            result.put("endDate", DateUtils.format(assemblyDaily2Dto.getEndDate(), DateUtils.DATE_TIME_PATTERN));

        }
        //工作时间
        String workTimeMapJson = String.valueOf(result.get("workTimeMap"));
        result.putAll(JSON.parseObject(workTimeMapJson, Map.class));
        String workTimeMapJson2 = String.valueOf(assemblyDaily2Dto.getWorkTimeMap2());
        log.error("assemblyDaily2Dto.getWorkTimeMap2()：{}", assemblyDaily2Dto.getWorkTimeMap2());
        List<WorkTimeVO> workTimeMap2 = ObjectUtils.isEmpty(workTimeMapJson2) ? null : JSON.parseArray(workTimeMapJson2, WorkTimeVO.class);


        //前端展示的是世界时区，所以要转成世界时区
        if (!ObjectUtils.isEmpty(workTimeMap2)) {
            for (WorkTimeVO timeVO : workTimeMap2) {
                if (!ObjectUtils.isEmpty(timeVO.getValue2()) && !ObjectUtils.isEmpty(timeVO.getValue2().get(0))) {
                    List<Date> value2 = new ArrayList<>();
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(timeVO.getValue2().get(0));
                    calendar.set(Calendar.HOUR, calendar.get(Calendar.HOUR) - 8);
                    value2.add(calendar.getTime());
                    Calendar calendar2 = Calendar.getInstance();
                    calendar2.setTime(timeVO.getValue2().get(1));
                    calendar2.set(Calendar.HOUR, calendar2.get(Calendar.HOUR) - 8);
                    value2.add(calendar2.getTime());
                    timeVO.setValue2(value2);
                }
                if (!ObjectUtils.isEmpty(timeVO.getValue1()) && !ObjectUtils.isEmpty(timeVO.getValue1().get(0))) {
                    List<Date> value1 = new ArrayList<>();
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(timeVO.getValue1().get(0));
                    calendar.set(Calendar.HOUR, calendar.get(Calendar.HOUR) - 8);
                    value1.add(calendar.getTime());
                    Calendar calendar2 = Calendar.getInstance();
                    calendar2.setTime(timeVO.getValue1().get(1));
                    calendar2.set(Calendar.HOUR, calendar2.get(Calendar.HOUR) - 8);
                    value1.add(calendar2.getTime());
                    timeVO.setValue1(value1);
                }
            }
        }
        result.put("tableData", workTimeMap2);

        if (ObjectUtils.isEmpty(result.get("dailyDetails"))) {
            return result;
        }
        List<Map<String, Object>> dailyDetails = JSON.parseObject(result.get("dailyDetails").toString(), new TypeReference<List<Map<String, Object>>>() {
        });
        dailyDetails.forEach(detail -> {
            if (!ObjectUtils.isEmpty(detail.get("feedingMaterial"))) {

                JSONArray feedingMaterial = JSON.parseArray(detail.get("feedingMaterial").toString());
                detail.put("feedingMaterial", feedingMaterial);
            }
        });
        result.put("dailyDetails", dailyDetails);
        result.remove("workTimeMap");
        return result;
    }

    @Override
    public void downloadExport(HttpServletResponse response, Long id) {
        AssemblyDaily2Dto assemblyDaily2Dto = dao.getDetailInfo2(id);
        HashMap<String, Object> mapResult = new HashMap<>();
        assemblyDaily2Dto.setIndicateDate2(DateUtils.format(assemblyDaily2Dto.getIndicateDate()));
        Map<String, Object> result = JSON.parseObject(JSON.toJSONString(assemblyDaily2Dto), new TypeReference<Map<String, Object>>() {
        });
        result.put("indicateDate", DateUtils.format((Date) result.get("indicateDate")));
        if (result.containsKey("startDate") && !ObjectUtils.isEmpty(result.get("startDate"))) {
//            result.put("indicateDate",assemblyDaily2Dto.getIndicateDate2());
            result.put("startDate", DateUtils.format(assemblyDaily2Dto.getStartDate(), DateUtils.DATE_TIME_PATTERN));
            result.put("endDate", DateUtils.format(assemblyDaily2Dto.getEndDate(), DateUtils.DATE_TIME_PATTERN));
            //日期
            mapResult.put("dateTime", DateUtils.format(assemblyDaily2Dto.getStartDate(), DateUtils.DATE_TIME_PATTERN) + "-" + DateUtils.format(assemblyDaily2Dto.getEndDate(), DateUtils.DATE_TIME_PATTERN));

        }
        //工作时间
        String workTimeMapJson = String.valueOf(result.get("workTimeMap"));
        result.putAll(JSON.parseObject(workTimeMapJson, Map.class));
        String workTimeMapJson2 = String.valueOf(assemblyDaily2Dto.getWorkTimeMap2());
        log.error("assemblyDaily2Dto.getWorkTimeMap2()：{}", assemblyDaily2Dto.getWorkTimeMap2());
        List<WorkTimeVO> workTimeMap2 = ObjectUtils.isEmpty(workTimeMapJson2) ? null : JSON.parseArray(workTimeMapJson2, WorkTimeVO.class);


        //前端展示的是世界时区，所以要转成世界时区
//        if (!ObjectUtils.isEmpty(workTimeMap2)) {
//            for (WorkTimeVO timeVO : workTimeMap2) {
//                if (!ObjectUtils.isEmpty(timeVO.getValue2()) && !ObjectUtils.isEmpty(timeVO.getValue2().get(0))) {
//                    List<Date> value2 = new ArrayList<>();
//                    Calendar calendar = Calendar.getInstance();
//                    calendar.setTime(timeVO.getValue2().get(0));
//                    calendar.set(Calendar.HOUR, calendar.get(Calendar.HOUR) + 8);
//                    value2.add(calendar.getTime());
//                    Calendar calendar2 = Calendar.getInstance();
//                    calendar2.setTime(timeVO.getValue2().get(1));
//                    calendar2.set(Calendar.HOUR, calendar2.get(Calendar.HOUR) + 8);
//                    value2.add(calendar2.getTime());
//                    timeVO.setValue2(value2);
//                }
//                if (!ObjectUtils.isEmpty(timeVO.getValue1()) && !ObjectUtils.isEmpty(timeVO.getValue1().get(0))) {
//                    List<Date> value1 = new ArrayList<>();
//                    Calendar calendar = Calendar.getInstance();
//                    calendar.setTime(timeVO.getValue1().get(0));
//                    calendar.set(Calendar.HOUR, calendar.get(Calendar.HOUR) + 8);
//                    value1.add(calendar.getTime());
//                    Calendar calendar2 = Calendar.getInstance();
//                    calendar2.setTime(timeVO.getValue1().get(1));
//                    calendar2.set(Calendar.HOUR, calendar2.get(Calendar.HOUR) + 8);
//                    value1.add(calendar2.getTime());
//                    timeVO.setValue1(value1);
//                }
//            }
//        }
        result.put("tableData", workTimeMap2);
        List<WorkTimeDO> listTime = new ArrayList();
        Long totalAllTime = 0l;
        String valueThing = "";
        String valuethingName = "";
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
        if (!ObjectUtils.isEmpty(workTimeMap2)){

        for (WorkTimeVO item : workTimeMap2) {
            WorkTimeDO workTimeDO = new WorkTimeDO();

            if(!ObjectUtils.isEmpty(item.getValue1())){
                workTimeDO.setWorkTime1(item.getValue1().size() == 1 || ObjectUtils.isEmpty(item.getValue1().get(0))  ? null : sdf.format(item.getValue1().get(0)));
                workTimeDO.setWorkTime2(item.getValue1().size() == 1 || ObjectUtils.isEmpty(item.getValue1().get(1))  ? null : sdf.format(item.getValue1().get(1)));
//                workTimeDO.setWorkTime1(item.getValue1().size() == 1 ? null : sdf.format(Date.parse(item.getValue1().get(0).toString())));
//                workTimeDO.setWorkTime2(item.getValue1().size() == 1 ? null : sdf.format(Date.parse(item.getValue1().get(1).toString())));
            }
            if(!ObjectUtils.isEmpty(item.getValue2())){
                workTimeDO.setNoworkTime1(item.getValue2().size() == 1 || ObjectUtils.isEmpty(item.getValue2().get(0)) ? null : sdf.format(item.getValue2().get(0)));
                workTimeDO.setNoworkTime2(item.getValue2().size() == 1 || ObjectUtils.isEmpty(item.getValue2().get(1)) ? null : sdf.format(item.getValue2().get(1)));
//                workTimeDO.setNoworkTime1(item.getValue2().size() == 1 ? null : sdf.format(Date.parse(item.getValue2().get(0).toString())));
//                workTimeDO.setNoworkTime2(item.getValue2().size() == 1 ? null : sdf.format(Date.parse(item.getValue2().get(1).toString())));
            }
            valueThing = item.getValuething();
            valuethingName = ObjectUtil.isEmpty(valueThing) ? "" :
                    (valueThing.equals("选项1") ? "排料时间" :
                            (valueThing.equals("选项2") ? "清扫时间" :
                                    (valueThing.equals("选项3") ? "维修时间" :
                                            (valueThing.equals("选项4") ? "开会时间" :
                                                    (valueThing.equals("选项5") ? "培训时间" :
                                                            (valueThing.equals("选项6") ? "其它" : ""))))));
            workTimeDO.setNoworkThing(valuethingName);
            workTimeDO.setPersonCount(item.getPersoncount() == null ? null : item.getPersoncount());
            String totalTime = item.getTotaltime() == null ? "00小时00分钟" : item.getTotaltime().toString();
            totalTime = totalTime.substring(totalTime.indexOf("天") + 1, totalTime.lastIndexOf("钟") + 1);
            workTimeDO.setTotalTime(item.getTotaltime() == null ? null : totalTime);
            //workTimeDO.setCategory(item.getCategory());
            workTimeDO.setCategoryJson(StringUtils.join(item.getCategory(), ","));
//            if (ObjectUtil.isNotEmpty(item.getTotaltime())) totalAllTime = totalAllTime + new Long(item.getTotaltime());
            listTime.add(workTimeDO);
        }

        }
        //合计作业时间、合计无勤时间、合计时间格式(00小时00分钟)
        //合计作业时间
        String totalWorkTime = result.get("totalWorkTime") == null ? "00小时00分钟" : result.get("totalWorkTime").toString();
        totalWorkTime = totalWorkTime.substring(totalWorkTime.indexOf("天") + 1, totalWorkTime.lastIndexOf("钟") + 1);
        mapResult.put("totalWorkTime", totalWorkTime);
//        mapResult.put("totalWorkTime",result.get("totalWorkTime"));
        //合计无勤时间
        String totalNoWorkTime = result.get("totalNoWorkTime") == null ? "00小时00分钟" : result.get("totalNoWorkTime").toString();
        totalNoWorkTime = totalNoWorkTime.substring(totalNoWorkTime.indexOf("天") + 1, totalNoWorkTime.lastIndexOf("钟") + 1);
        mapResult.put("totalNoWorkTime", totalNoWorkTime);
//        mapResult.put("totalNoWorkTime",result.get("totalNoWorkTime"));
        //合计人数
        mapResult.put("totalPersonCount", result.get("totalPersonCount"));
        //合计时间
        String totalAllTimeTemp = result.get("totalAllTime") == null ? "00天00小时00分钟" : result.get("totalAllTime").toString();
        totalAllTimeTemp = totalAllTimeTemp.substring(0,totalAllTimeTemp.lastIndexOf("钟") + 1);
        mapResult.put("totalAllTime", totalAllTimeTemp);
//        mapResult.put("totalAllTime",result.get("totalAllTime"));

        //决裁
        mapResult.put("approverName", result.get("approverName"));

        //辅助决裁
        mapResult.put("auditorName", result.get("auditorName"));

        //担当者
        mapResult.put("staffingName", result.get("staffingName"));

        //应出勤人员
        mapResult.put("shouldBeAttendance", result.get("shouldBeAttendance"));
        //实际出勤人员
        mapResult.put("realAttendance", result.get("realAttendance"));
        //出勤偏差
        mapResult.put("attendanceBias", result.get("attendanceBias"));
        //备注
        mapResult.put("remarks", result.get("remarks"));

        if (ObjectUtils.isEmpty(result.get("dailyDetails"))) {
            // return result;
        }
        List<Map<String, Object>> dailyDetails = JSON.parseObject(result.get("dailyDetails").toString(), new TypeReference<List<Map<String, Object>>>() {
        });
        dailyDetails.forEach(detail -> {
            if (!ObjectUtils.isEmpty(detail.get("feedingMaterial"))) {

                JSONArray feedingMaterial = JSON.parseArray(detail.get("feedingMaterial").toString());
                detail.put("feedingMaterial", feedingMaterial);
            }
        });
        result.put("dailyDetails", dailyDetails);
        List<DailyDetailDO> listDetailNew = new ArrayList<>();
        List<FeedingMaterialDO> feedingMaterialList = new ArrayList<>();
        List<DailyDetailDO> listDetail = JSON.parseArray(JSON.toJSONString(dailyDetails), DailyDetailDO.class);
        for (DailyDetailDO dailyDetailDO : listDetail) {
            for (int i = 0; i < 4; i++) {
                listDetailNew.add(dailyDetailDO);
            }
            List<FeedingMaterialDO> listItem = dailyDetailDO.getFeedingMaterial();
            int size = listItem.size();
            if (size < 4) {
                for (int j = 0; j < 4 - size; j++) {
                    FeedingMaterialDO feedingMaterialDO = new FeedingMaterialDO();
                    listItem.add(feedingMaterialDO);
                }
            }
            feedingMaterialList.addAll(listItem);
        }
        //特记与传达事项
        mapResult.put("specialNoteItem", result.get("specialNoteItem"));
        String excelName = "组装日报";
        String templateFileName = localPath + File.separator + basePath + File.separator + "templates" + File.separator + "zzrb.xlsx";
        try {
            ExcelUtil.exportExcel(response, listDetailNew, listTime, feedingMaterialList, mapResult, excelName, templateFileName, "组装日报");
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 将日期减去8小时
     * @param date
     * @return
     */
    private Date timeConversion(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR_OF_DAY, -8);
        return calendar.getTime();
    }

    @Override
    public List<AssemblyDaily2Dto> listDetail(Map<String, Object> param) {
        return dao.listDetail(param);
    }

    @Override
    public Integer update(AssemblyDailyDO entity) {
        return dao.update(entity);
    }

    @Override
    public Integer update(AssemblyDailyDto dto) {
        Map<String, String> map = new HashMap<>();
        map.put("startTime1", dto.getStartTime1());
        map.put("startTime2", dto.getStartTime2());
        map.put("startTime3", dto.getStartTime3());
        map.put("startTime4", dto.getStartTime4());
        map.put("startTime5", dto.getStartTime5());
        map.put("startTime6", dto.getStartTime6());
        map.put("startTime7", dto.getStartTime7());
        map.put("startTime8", dto.getStartTime8());
        map.put("startTime9", dto.getStartTime9());
        map.put("startTime10", dto.getStartTime10());
        map.put("endTime1", dto.getEndTime1());
        map.put("endTime2", dto.getEndTime2());
        map.put("endTime3", dto.getEndTime3());
        map.put("endTime4", dto.getEndTime4());
        map.put("endTime5", dto.getEndTime5());
        map.put("endTime6", dto.getEndTime6());
        map.put("endTime7", dto.getEndTime7());
        map.put("endTime8", dto.getEndTime8());
        map.put("endTime9", dto.getEndTime9());
        map.put("endTime10", dto.getEndTime10());
        map.put("thing1", dto.getThing1());
        map.put("thing2", dto.getThing2());
        map.put("thing3", dto.getThing3());
        map.put("thing4", dto.getThing4());
        map.put("thing5", dto.getThing5());

        dto.setWorkTimeMap(JSON.toJSONString(map));
        AssemblyDailyDO entity = new AssemblyDailyDO();
        SpringUtils.copyPropertiesIgnoreNull(dto, entity);

        int result = dao.update(entity);
        if (result > AslConstant.ZERO) {
            return result;
        }
        return AslConstant.ZERO;
    }

    @Override
    public int batchRemove(Long[] ids) {
        return dao.batchRemove(ids);
    }

    @Override
    public int remove(Long id) {
        return dao.remove(id);
    }

    @Override
    public int countForMap(Map<String, Object> params) {
        return dao.countForMap(params);
    }

    @Override
    public List<Map<String, Object>> listForMap(Map<String, Object> param) {
        return dao.listForMap(param);
    }

    @Override
    public Integer syncSaveToK32(AssemblyDailyDO entity) {
        //组装日报详情
        AssemblyDaily2Dto assemblyDaily2Dto = dao.getDetailInfo2(entity.getId());
        String batch = DateUtil.format(new Date(), "yyyyMMdd");
        List<AssemblyDailyDetailDtO> dailyDetails = assemblyDaily2Dto.getDailyDetails();
        if (ObjectUtils.isEmpty(assemblyDaily2Dto) || ObjectUtils.isEmpty(dailyDetails)) {
            return 0;
        }
        UserDO userDO = userService.get(assemblyDaily2Dto.getCreateBy());
        //投料单
        List<Long> aiIds = assemblyDaily2Dto.getDailyDetails().stream().map(AssemblyDailyDetailDtO::getAiId).distinct().collect(Collectors.toList());
        HashMap<String, Object> map = new HashMap<>();
        map.put("instructionIds", aiIds);
        List<ProductionFeedingDetailDO> feedingDetails = productionFeedingDetailDao.feedingItemList(map);
        Map<String, ProductionFeedingDetailDO> detailDOMap = feedingDetails.stream().collect(Collectors.toMap(o -> o.getPlanId() + "_" + o.getMaterielId(), v -> v, (v1, v2) -> v1));

        List<StockOutItemDO> feedItems = new ArrayList<>();
//        List<StockInItemDO> badItems = new ArrayList<>();
        List<StockInItemDO> qualifiedCollect = new ArrayList<>();
        StockOutDO stockOut = new StockOutDO();
        StockInDO stockIn = new StockInDO();
        stockOut.setOperator(ShiroUtils.getUserId());
        stockIn.setOperator(ShiroUtils.getUserId());
        stockIn.setSourceCompany(ShiroUtils.getUser().getDeptId());

        log.error("==========================查询库存======================================");
        String filter = "and 仓库ID='" + Constant.warehouse6 + "'";
        Triple<Boolean, String, List<KisReceiveStockVo>> stockList = kisBasicsService.realTimeStockBalanceEnquiry2(filter);
        if (!stockList.getLeft()) {
            String msg = stockList.getMiddle();
            log.error("==========================88888888888888888======================================");
            throw new BDException(msg);
        }

        List<KisReceiveStockVo> stockVos = stockList.getRight();
        log.error("==========================stockVos======================================");
        log.error(JSON.toJSONString(stockVos));
        for (int i = 0; i < dailyDetails.size(); i++) {
            String feedings = dailyDetails.get(i).getFeedingMaterial();
            if (ObjectUtils.isEmpty(feedings)) continue;
            JSONArray feedingMaterial = JSON.parseArray(feedings);
            //1、使用数量：领料车间库
            List<Object> feedCollect = feedingMaterial.stream().filter(feeding -> {
                JSONObject jsonObject = (JSONObject) feeding;
                return (StringUtils.isNotBlank(jsonObject.getString("materielId")) &&
                        StringUtils.isNotBlank(jsonObject.getString("planFeeding")));
            }).collect(Collectors.toList());
            if (ObjectUtils.isEmpty(feedCollect)) continue;
            Integer num = new Integer(i);
            Map<String, List<KisReceiveStockVo>> stockGroupByStock = stockVos.stream()
                    .filter(s -> !ObjectUtils.isEmpty(s) && !ObjectUtils.isEmpty(s.getFQty()) && new BigDecimal(s.getFQty()).compareTo(BigDecimal.ONE) > 0).collect(Collectors.groupingBy(vo -> vo.getFStockID() + "_" + vo.getFItemID()));
            Map<String, BigDecimal> totalGroupByStock = stockVos.stream().filter(s -> !ObjectUtils.isEmpty(s) && !ObjectUtils.isEmpty(s.getFQty()) && new BigDecimal(s.getFQty()).compareTo(BigDecimal.ZERO) > 0)
                    .collect(Collectors.groupingBy(vo -> vo.getFStockID() + "_" + vo.getFItemID(), CustomCollectors.summingBigDecimal(vo -> new BigDecimal(vo.getFQty()))));
            for (int b = 0; b < feedingMaterial.size(); b++) {
                JSONObject jsonObject = (JSONObject) feedingMaterial.get(b);
                Long materielId = new Long(jsonObject.getString("materielId"));
                BigDecimal count = new BigDecimal(jsonObject.getString("planFeeding"));
                if (count.compareTo(BigDecimal.ZERO) <= 0) continue;
                List<KisReceiveStockVo> kisReceiveStockVos = stockGroupByStock.get(Constant.warehouse6 + "_" + materielId);
                BigDecimal total = totalGroupByStock.get(Constant.warehouse6 + "_" + materielId);
                if (ObjectUtils.isEmpty(kisReceiveStockVos) || total.compareTo(count) < 0) {
                    log.error("==========================stockGroupByStock：{}", JSON.toJSONString(stockGroupByStock));
                    log.error("==========================totalGroupByStock：{}", JSON.toJSONString(totalGroupByStock));
                    log.error("==========================kisReceiveStockVos{}", JSON.toJSONString(kisReceiveStockVos));
                    log.error("==========================total: {}", total);
                    log.error("==========================count: {}", count);
                    MaterielDO materielDO = materielService.get(materielId);
                    FacilityDO facilityDO = facilityService.get(Constant.warehouse6);
                    String materielName = ObjectUtils.isEmpty(materielDO) ? materielId.toString() : materielDO.getName();
                    String facilityName = ObjectUtils.isEmpty(facilityDO) ? Constant.warehouse6.toString() : facilityDO.getName();
                    throw new BDException("物料" + materielName + "在仓库" + facilityName + "的库存不足，不能领料");
                }
                ProductionFeedingDetailDO detailDO = detailDOMap.get(dailyDetails.get(num).getPlanId().toString() + "_" + materielId);
                BigDecimal residue = new BigDecimal(jsonObject.getString("planFeeding"));
                for (int j = 0; j < kisReceiveStockVos.size(); j++) {
                    KisReceiveStockVo stockVo = kisReceiveStockVos.get(j);
                    BigDecimal fQty = new BigDecimal(stockVo.getFQty());
                    if (fQty.compareTo(BigDecimal.ZERO) <= 0) continue;
                    if (fQty.compareTo(residue) >= 0) {
                        StockOutItemDO itemDO = new StockOutItemDO();
                        itemDO.setMaterielId(materielId);
                        itemDO.setWarehouse(Constant.warehouse6);
                        itemDO.setWarehLocation(new Long(stockVo.getFStockPlaceID()));
                        itemDO.setCount(residue);
                        itemDO.setSourceInteridEntryid(detailDO.getInteridEntryid());
                        itemDO.setSourceCode(detailDO.getFeedingNo());
                        itemDO.setBatch(stockVo.getFBatchNo());
                        itemDO.setUuid(UUID.randomUUID().toString());
                        feedItems.add(itemDO);
                        stockVo.setFQty(fQty.subtract(residue).toString());
                        break;
                    } else {
                        StockOutItemDO itemDO = new StockOutItemDO();
                        itemDO.setMaterielId(materielId);
                        itemDO.setWarehouse(Constant.warehouse6);
                        itemDO.setWarehLocation(new Long(stockVo.getFStockPlaceID()));
                        itemDO.setCount(fQty);
                        itemDO.setSourceInteridEntryid(detailDO.getInteridEntryid());
                        itemDO.setSourceCode(detailDO.getFeedingNo());
                        itemDO.setBatch(stockVo.getFBatchNo());
                        itemDO.setUuid(UUID.randomUUID().toString());
                        feedItems.add(itemDO);
                        residue = residue.subtract(fQty);
                        stockVo.setFQty("0");
                    }
                }
            }


            //3、合格数量：入库车间库
            Integer num2 = new Integer(i);
            if (!ObjectUtils.isEmpty(dailyDetails.get(i).getQualifiedQty()) && dailyDetails.get(i).getQualifiedQty().compareTo(BigDecimal.ZERO) > 0) {
                StockInItemDO itemDO = new StockInItemDO();
                itemDO.setMaterielId(dailyDetails.get(i).getMaterielId());
                itemDO.setWarehouse(Constant.warehouse8);
                itemDO.setWarehLocation(Constant.warehLocation9);
//                itemDO.setWarehLocation(0l);
                itemDO.setBatch(batch);
                itemDO.setCount(dailyDetails.get(i).getQualifiedQty());
                itemDO.setSourceInteridEntryid(dailyDetails.get(num2).getPlanId().toString());
                itemDO.setSourceCode(dailyDetails.get(num2).getPlanCode().toString());
                itemDO.setUuid(UUID.randomUUID().toString());
                qualifiedCollect.add(itemDO);
            }
        }
        //2、不良数量：入库不良品库
//        badItems = dailyDetails.stream().filter(detail -> !ObjectUtils.isEmpty(detail.getInspectionQty()) && detail.getInspectionQty().compareTo(BigDecimal.ZERO) > 0).map(detail -> {
//            StockInItemDO itemDO = new StockInItemDO();
//            itemDO.setMaterielId(detail.getMaterielId());
//            itemDO.setWarehouse(Constant.warehouse7);//附属品库
//            itemDO.setWarehLocation(Constant.warehLocation7);
////            itemDO.setWarehLocation(0l);
//            itemDO.setCount(detail.getInspectionQty());
//            itemDO.setSourceInteridEntryid(detail.getPlanId().toString());
//            itemDO.setSourceCode(detail.getPlanCode().toString());
//            itemDO.setUuid(UUID.randomUUID().toString());
//            return itemDO;
//        }).collect(Collectors.toList());
        ArrayList<SyncLogDO> syncLogDOS = new ArrayList<>();
        if (!ObjectUtils.isEmpty(feedItems)) {
            log.error("==========================子件使用数量 使用数量：领料车间库======================================");
            //领料
            Triple<Boolean, String, String> triple = this.outConversionSync(stockOut, feedItems, userDO);
            if (!triple.getLeft()) {
                throw new BDException(triple.getMiddle());
            }
            Triple<Boolean, String, ApiResultVO2S> checkResult = kisBillOfPushService.checkK3LinLiao2(ShiroUtils.getUser().getToken(), triple.getRight(), ShiroUtils.getUser().getName(), true);
            if (!checkResult.getLeft()) {
                throw new BDException(checkResult.getMiddle());
            }
            SyncLogDO syncLogDO = new SyncLogDO();
            String content = "组装日报使用数量领料单据编号：" + triple.getRight() + "需要反审核";
            syncLogDO.setContent(content);
            syncLogDO.setType(1);
            syncLogDOS.add(syncLogDO);
        }
//        if (!ObjectUtils.isEmpty(badItems)){
//            log.error("==========================不良数量：入库不良品库======================================");
//            //调拨
//            Triple<Boolean, String, String> triple = kisBillOfPushService.inputTypeParamConversionSync2(1, 2, badItems,stockIn);
//            if (!triple.getLeft()) {
//                productionFeedingDetailDao.batchSaveSyncLog(syncLogDOS);
//                throw new BDException(triple.getMiddle());
//            }
//            Triple<Boolean, String, ApiResultVO2S> checkResult = kisBillOfPushService.checkK3In(ShiroUtils.getUser().getToken(), triple.getRight(), ShiroUtils.getUser().getName(),true);
//            if (!checkResult.getLeft()) {
//                productionFeedingDetailDao.batchSaveSyncLog(syncLogDOS);
//                throw new BDException(checkResult.getMiddle());
//            }
//            SyncLogDO syncLogDO = new SyncLogDO();
//            String content = "组装日报不良品入库单据编号："+triple.getRight()+"需要反审核";
//            syncLogDO.setContent(content);
//            syncLogDO.setType(1);
//            syncLogDOS.add(syncLogDO);
//        }
        if (!ObjectUtils.isEmpty(qualifiedCollect)) {
            log.error("==========================合格数量：入库车间库======================================");
            Triple<Boolean, String, String> triple = kisBillOfPushService.inputTypeParamConversionSync2(1, 2, qualifiedCollect, stockIn, userDO);
            if (!triple.getLeft()) {
                productionFeedingDetailDao.batchSaveSyncLog(syncLogDOS);
                throw new BDException(triple.getMiddle());
            }
            Triple<Boolean, String, ApiResultVO2S> checkResult = kisBillOfPushService.checkK3In(ShiroUtils.getUser().getToken(), triple.getRight(), ShiroUtils.getUser().getName(), true);
            if (!checkResult.getLeft()) {
                productionFeedingDetailDao.batchSaveSyncLog(syncLogDOS);
                throw new BDException(checkResult.getMiddle());
            }
        }
        return 2;
    }

//    @Override
//    public Integer syncSaveToK3(AssemblyDailyDO entity) {
//        Map<String, Object> param = new HashMap<>();
//        List<StockOutItemDO> feedItems = new ArrayList<>();
//        List<StockInItemDO> badItems = new ArrayList<>();
//
//        //生产任务单id
//        Map<String, Object> assemblyInstructionDO = assemblyInstructionService.getDetail(entity.getId());
//
//        Object planId = assemblyInstructionDO.get("planId");
//
//        HashMap<String, Object> map = new HashMap<>();
//        ArrayList planIds = new ArrayList();
//        planIds.add(planId);
//        map.put("planIds",planIds);
//        List<ProductionFeedingDetailDO> feedingDetails = productionFeedingDetailDao.feedingItemList(map);
//        Map<Long, ProductionFeedingDetailDO> detailDOMap = feedingDetails.stream().collect(Collectors.toMap(ProductionFeedingDetailDO::getMaterielId, v -> v, (v1, v2) -> v1));
////        param.put("planId", assemblyInstructionDO.get("planId"));
////
////
////        //单据日期
////        param.put("indicateDate", entity.getIndicateDate());
////
////        //生产数量
////        param.put("productionQty", entity.getProductionQty());
////        //不良数量
////        param.put("inspectionQty", entity.getInspectionQty());
//
//        //原料投入量
//        String feedingMaterialJson = entity.getFeedingMaterial();
//        JSONArray feedingMaterial = JSON.parseArray(feedingMaterialJson);
////        param.put("feedingMaterial", feedingMaterial);
////        BigDecimal
//        //调用接口，传递生产任务汇报单、K3产品入库单、生产领料单,调拨单
//        StockOutDO stockOut = new StockOutDO();
//        StockInDO stockIn = new StockInDO();
//        stockOut.setOperator(ShiroUtils.getUserId());// bl  planFeeding
//        stockIn.setOperator(ShiroUtils.getUserId());// bl  planFeeding
//        stockIn.setSourceCompany(ShiroUtils.getUser().getDeptId());
//
//        //1、使用数量：领料车间库
//        List<Object> feedCollect = feedingMaterial.stream().filter(feeding -> {
//            JSONObject jsonObject = (JSONObject) feeding;
//            return (StringUtils.isNotBlank(jsonObject.getString("materielId")) &&
//                    StringUtils.isNotBlank(jsonObject.getString("planFeeding")));
//        }).collect(Collectors.toList());
//        if (!ObjectUtils.isEmpty(feedCollect)){
//            feedItems = feedCollect.stream().map(feeding -> {
//                JSONObject jsonObject = (JSONObject) feeding;
//                Long materielId = new Long(jsonObject.getString("materielId"));
//                ProductionFeedingDetailDO detailDO = detailDOMap.get(materielId);
//                StockOutItemDO itemDO = new StockOutItemDO();
//                itemDO.setMaterielId(new Long(jsonObject.getString("materielId")));
//                itemDO.setWarehouse(Constant.warehouse6);//车间库
//                itemDO.setCount(new BigDecimal(jsonObject.getString("planFeeding")));
//                itemDO.setSourceInteridEntryid(detailDO.getInteridEntryid());
//                itemDO.setSourceCode(detailDO.getFeedingNo());
//                itemDO.setUuid(UUID.randomUUID().toString());
//                return itemDO;
//            }).collect(Collectors.toList());
//            log.error("==========================使用数量：领料车间库======================================");
//            //领料
//            Triple<Boolean, String, String> triple = this.outConversionSync(stockOut, feedItems);
//            if (!triple.getLeft()) {
//                throw new BDException(triple.getMiddle());
//            }
////            Triple<Boolean, String, ApiResultVO2S> checkResult = kisBillOfPushService.checkK3LinLiao(ShiroUtils.getUser().getToken(), triple.getRight(), "吴燕",true);
////            if (!checkResult.getLeft()) {
////                throw new BDException(checkResult.getMiddle());
////            }
//        }
//
//        //2、不良数量：入库不良品库
//        List<Object> badCollect = feedingMaterial.stream().filter(feeding -> {
//            JSONObject jsonObject = (JSONObject) feeding;
//            return (StringUtils.isNotBlank(jsonObject.getString("materielId")) &&
//                    StringUtils.isNotBlank(jsonObject.getString("bl")));
//        }).collect(Collectors.toList());
//        if (!ObjectUtils.isEmpty(badCollect)){
//            badItems = badCollect.stream().map(feeding -> {
//                JSONObject jsonObject = (JSONObject) feeding;
//                StockInItemDO itemDO = new StockInItemDO();
//                itemDO.setMaterielId(new Long(jsonObject.getString("materielId")));
//                itemDO.setWarehouse(Constant.warehouse7);
//                itemDO.setWarehLocation(Constant.warehLocation7);//批号
//                itemDO.setCount(new BigDecimal(jsonObject.getString("bl")));
//                itemDO.setSourceInteridEntryid(assemblyInstructionDO.get("planId").toString());
//                itemDO.setSourceCode(assemblyInstructionDO.get("planCode").toString());
//                itemDO.setUuid(UUID.randomUUID().toString());
//                return itemDO;
//            }).collect(Collectors.toList());
////            if (!ObjectUtils.isEmpty(entity) && !ObjectUtils.isEmpty(entity.getInspectionQty())){
////                StockInItemDO itemDO = new StockInItemDO();
////                itemDO.setMaterielId(entity.getMaterielId());
////                itemDO.setWarehouse(329l);
////                itemDO.setWarehLocation(33l);//批号
////                itemDO.setCount(entity.getInspectionQty());
////                itemDO.setSourceInteridEntryid(assemblyInstructionDO.get("planId").toString());
////                itemDO.setSourceCode(assemblyInstructionDO.get("planCode").toString());
////                itemDO.setUuid(UUID.randomUUID().toString());
////                badItems.add(itemDO);
////            }
//            log.error("==========================不良数量：入库不良品库======================================");
//            //todo 金蝶怎么回滚 批号填啥 库位
//            //调拨
//            Triple<Boolean, String, String> triple = kisBillOfPushService.inputTypeParamConversionSync2(1, 2, badItems,stockIn);
//            if (!triple.getLeft()) {
//                throw new BDException(triple.getMiddle());
//            }
////            Triple<Boolean, String, ApiResultVO2S> checkResult = kisBillOfPushService.checkK3In(ShiroUtils.getUser().getToken(), triple.getRight(), "吴燕",true);
////            if (!checkResult.getLeft()) {
////                throw new BDException(triple.getMiddle());
////            }
//
//        }
//        //3、合格数量：入库车间库
//        if (!ObjectUtils.isEmpty(entity) && !ObjectUtils.isEmpty(entity.getInspectionQty())){
//            List<StockInItemDO> qualifiedCollect = new ArrayList<>();
//            StockInItemDO itemDO = new StockInItemDO();
//            itemDO.setMaterielId(entity.getMaterielId());
//            itemDO.setWarehouse(Constant.warehouse8);//成品库
//            itemDO.setWarehLocation(Constant.warehLocation8);//批号
//            log.error("==========================Constant.warehouse8======================================"+Constant.warehouse8);
//            log.error("==========================Constant.warehLocation8======================================"+Constant.warehLocation8);
//
////            itemDO.setWarehouse(282l);
////            itemDO.setWarehLocation(33l);//批号
//            itemDO.setCount(entity.getQualifiedQty());
//            itemDO.setSourceInteridEntryid(assemblyInstructionDO.get("planId").toString());
//            itemDO.setSourceCode(assemblyInstructionDO.get("planCode").toString());
//            itemDO.setUuid(UUID.randomUUID().toString());
//            qualifiedCollect.add(itemDO);
//            log.error("==========================合格数量：入库车间库======================================");
//            Triple<Boolean, String, String> triple = kisBillOfPushService.inputTypeParamConversionSync2(1, 2, qualifiedCollect,stockIn);
//            if (!triple.getLeft()) {
//                throw new BDException(triple.getMiddle());
//            }
////            Triple<Boolean, String, ApiResultVO2S> checkResult = kisBillOfPushService.checkK3In(ShiroUtils.getUser().getToken(), triple.getRight(), "吴燕",true);
////            if (!checkResult.getLeft()) {
////                throw new BDException(triple.getMiddle());
////            }
//        }
//
////        String result = kingdeeMiddlewareService.zuZhuangsaveSync(JSON.toJSONString(param));
////        JSONObject resultObj = JSON.parseObject(result);
////        if (!resultObj.getString("code").equals("0")) {
////            log.info(resultObj.getString("msg"));
////            return AslConstant.ZERO;
////        }
////        if (Objects.equals(r.get("code"),500)){
////            throw new BDException((String) r.getOrDefault("msg","系统错误，请联系管理员"));
////        }
//        return AslConstant.ONE;
//    }

//    /**
//     * 生产领料
//     * @param stockOutDO
//     * @param itemDOs
//     * @return
//     */
//    public Pair<Boolean, String> outConversionSync(StockOutDO stockOutDO, List<StockOutItemDO> itemDOs){
//        DictionaryDO storageType = dictionaryService.get(ConstantForGYL.LYCK);
//        Long storageTypeId = storageType.getId();
//        Pair<Boolean, String> pair = kisBillOfPushService.masterSwitchForOutboundSync(storageTypeId.intValue(), itemDOs, stockOutDO);
//        return pair;
//    }

    /**
     * 领料
     *
     * @param stockOutDO
     * @param itemDOs
     * @return
     */
    public Triple<Boolean, String, String> outConversionSync(StockOutDO stockOutDO, List<StockOutItemDO> itemDOs, UserDO userDO) {
        DictionaryDO storageType = dictionaryService.get(ConstantForGYL.LYCK);
        Long storageTypeId = storageType.getId();
        Triple<Boolean, String, String> triple = kisBillOfPushService.outTypeParamConversionSync2(1, 24, itemDOs, stockOutDO, userDO);
        return triple;
    }

    @Override
    public int totalForMap(Map<String, Object> param) {
        return dao.totalForMap(param);
    }
}
